#include "Direct3D.h"
//ctor
CD3D::CD3D(void)
{
	// initialize the D3D10device, swapchain and render target variables
	p_d3dDevice = NULL;
	p_dx10swapChain = NULL;
	p_RenderTargetView = NULL;
};

//dtor
CD3D::~CD3D(void)
{
	// release the variables if the destructor is called
	if(p_d3dDevice)
		p_d3dDevice->ClearState();

	if(p_RenderTargetView)
		p_RenderTargetView->Release();

	if(p_d3dDevice)
		p_d3dDevice->Release();

	if(p_dx10swapChain)
		p_dx10swapChain->Release();
};


// D3D Initialization function declaration
HRESULT CD3D::Initialize(HWND hWind)
{
	// define and declare the hresult variable
    HRESULT hresult_ = S_OK;

	// setup the rectanlge width and height of the swapchain according ot the ones used in the window handle
	RECT rectangle;
	GetClientRect(hWind, &rectangle);

	int rectangle_width = rectangle.right - rectangle.left;
	int rectangle_height = rectangle.bottom - rectangle.top;
	int deviceFlags = 0;
	

	// setup and create the swap chain
	DXGI_SWAP_CHAIN_DESC swapchain;
	SecureZeroMemory(&swapchain, sizeof(swapchain));
    
	swapchain.BufferCount = 1;
	swapchain.BufferDesc.Width = rectangle_width;
	swapchain.BufferDesc.Height = rectangle_height;
	swapchain.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	swapchain.BufferDesc.RefreshRate.Numerator = 30;
	swapchain.BufferDesc.RefreshRate.Denominator = 1;
	swapchain.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	swapchain.OutputWindow = hWind;
	swapchain.SampleDesc.Count = 1;
	swapchain.SampleDesc.Quality = 0;
	swapchain.Windowed = TRUE;

		// create the D3D  Device and the swap chain using the pre-defined options
		hresult_ = D3D10CreateDeviceAndSwapChain(
						NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL,
						deviceFlags, D3D10_SDK_VERSION,
						&swapchain, &p_dx10swapChain,
						&p_d3dDevice);

	// if either fail to create return false and close.
	if(FAILED(hresult_))
		return hresult_;

	// specify the render target view and set it up
	ID3D10Texture2D *pBuffer;
	hresult_ = p_dx10swapChain->GetBuffer(0, __uuidof(ID3D10Texture2D),(LPVOID*) &pBuffer);

	// if creation fails close the program
	if(FAILED(hresult_))
		return hresult_;

	// create the render target view
	hresult_ = p_d3dDevice->CreateRenderTargetView(pBuffer, NULL, &p_RenderTargetView);

	//release the placeholder buffer and delete it
	pBuffer->Release();

	// if the target view fails to be created stop the program
	if(FAILED(hresult_))
		return hresult_;
	// bind the render target to the output merger stage
	p_d3dDevice->OMSetRenderTargets(1,&p_RenderTargetView, NULL);

	// create the viewport for the window
	D3D10_VIEWPORT viewport;
	viewport.TopLeftX 	= 0;
	viewport.TopLeftY 	= 0;
	viewport.Width 		= rectangle_width;
	viewport.Height 	= rectangle_height;
	viewport.MinDepth 	= 0.0f;
	viewport.MaxDepth 	= 1.0f;

	// set the viewport and bind it to the rasterizer stage
	p_d3dDevice->RSSetViewports(1, &viewport);


	// return true if the program executes properly
	return S_OK;
};
// draw function declaration
void CD3D::Draw()
{
	// switch the back and front buffer and display
	p_dx10swapChain->Present(1,0);
};

void CD3D::BeginScene(float red, float green, float blue, float alpha)
{
	float color[4];
	color[0] = red;
	color[1] = green;
	color[2] = blue;
	color[3] = alpha;

	p_d3dDevice->ClearRenderTargetView(p_RenderTargetView, color);

};

void CD3D::EndScene()
{
	p_dx10swapChain->Present(0, 0);

	return;
}